package com.qianlima.upload.infrastructure.utils;

/**
 * @description: 文件上传工具类
 * @author：allms
 * @date: 2023/3/21 15:20
 */

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Component
public class FileUploadUtil {

    @Value("${file.local.path}")
    private String filePath;

    /**
     * 将文件切分成多个小块
     *
     * @param file      待上传的文件
     * @param chunkSize 每个小块的大小，单位为字节
     * @param tempDir   临时文件夹路径
     * @return 分片文件列表
     * @throws IOException
     */
    public static List<File> splitFile(File file, int chunkSize, String tempDir) throws IOException {
        List<File> chunkFiles = new ArrayList<>();
        try (InputStream input = Files.newInputStream(file.toPath())) {
            byte[] buffer = new byte[chunkSize];
            int bytesRead;
            int chunkIndex = 0;
            while ((bytesRead = input.read(buffer)) != -1) {
                File chunkFile = new File(tempDir, String.valueOf(chunkIndex));
                try (OutputStream output = Files.newOutputStream(chunkFile.toPath())) {
                    output.write(buffer, 0, bytesRead);
                }
                chunkFiles.add(chunkFile);
                chunkIndex++;
            }
        }
        return chunkFiles;
    }

    /**
     * 定义一个方法，接收一个MultipartFile对象和一个子目录名，返回一个文件的相对路径
     *
     * @param file   前端传来的文件
     * @param subDir
     * @return
     * @throws IOException
     */
    public String uploadFile(MultipartFile file, String subDir) throws IOException {
        //判断文件是否为空
        if (file.isEmpty()) {
            throw new IllegalArgumentException("文件内容为空，请重新选择文件！");
        }
        //获取文件的原始名称
        String originalFilename = file.getOriginalFilename();
        //获取文件的扩展名
        String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
        //生成一个新的文件名，避免重复
        String newFilename = UUID.randomUUID() + extension;
        //拼接子目录和新文件名，得到相对路径
        String relativePath = subDir + "/" + newFilename;
        //拼接根目录和相对路径，得到绝对路径
        String absolutePath = filePath + relativePath;
        //创建File对象，表示要保存的文件
        File destFile = new File(absolutePath);
        //判断父目录是否存在，不存在则创建
        if (!destFile.getParentFile().exists()) {
            destFile.getParentFile().mkdirs();
        }
        //将MultipartFile对象转换为File对象，并保存到本地目录
        file.transferTo(destFile);

        return relativePath;
    }
}
